﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Web;
using Common;
using Controladores;
using Entidades;
using Entidades.jSON;
using Web.Pages;

namespace Web.Helpers
{
    public class MailHelper
    {
        #region Public Methods

        public static Dictionary<string, string> CreateRecipientsList(string mailAddress, string displayName)
        {
            return new Dictionary<string,string> { { mailAddress, displayName} };
        }

        /// <summary>
        /// Enviar mail de recuperacion de contraseña
        /// </summary>
        /// <param name="destinatarios"></param>
        /// <param name="asunto"></param>
        /// <param name="arrCuerpo"></param>
        /// <param name="encoding"></param>
        /// <param name="html"></param>
        public static bool EnviarMailRecuperacionPassword(Dictionary<string, string> destinatarios, string[] arrCuerpo)
        {
            var resultado = false;
            try 
	        {	        
                var usuario  = arrCuerpo[0];
                var password = arrCuerpo[1];
                var email    = arrCuerpo[2];

                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;' >Datos del Usuario</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%' >");
                    sb.Append("<colgroup><col width='30%' /><col width='30%' /><col width='40%' /></colgroup>");
                    sb.Append("<tr>");    
                    sb.Append("<thead>");
                    sb.Append("<th>Usuario</th>");
	                sb.Append("<th>Password</th>");
                    sb.Append("<th>Email</th>");
                    sb.Append("</thead>");    
                    sb.Append("</tr>");    
                    sb.Append("<tbody>");
                    sb.Append("<tr style='text-align:center'>");
                    sb.Append("<td>" + usuario + "</td>");
                    sb.Append("<td>" + password + "</td>");
                    sb.Append("<td>" + email + "</td>");
                    sb.Append("</tr>");
                    sb.Append("</tbody>");
                    sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

                resultado = MailClient().SendMail(destinatarios, "Recuperación de password", cuerpo);
            }
            catch (Exception)
            {
                throw;
            }
            return resultado;
        }

        /// <summary>
        /// Enviar mail de reclamo
        /// </summary>
        /// <param name="destinatarios"></param>
        /// <param name="asunto"></param>
        /// <param name="tituloGuion"></param>
        /// <param name="descripcion"></param>
        /// <param name="fecha"></param>
        /// <param name="usuario"></param>
        /// <returns></returns>
        public static bool EnviarMailReclamo(Dictionary<string, string> destinatarios, string asunto, string tituloGuion, string descripcion, DateTime fecha, string usuario)
        {
            var resultado = false;
            try 
	        {	        
                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;' >Datos del reclamo</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%' >");
                    sb.Append("<colgroup><col width='100%' /></colgroup>");
                    sb.Append("<tr><td><label>Fecha:</label></td></tr>");
                    sb.Append("<tr><td><input type='text' style='width:98%' readonly='readonly' value='" + fecha.ToShortDateString() + "' /></td></tr>");
                    sb.Append("<tr><td><label>Asunto:</label></td></tr><tr>");
                    sb.Append("<td><input type='text' style='width:98%' readonly='readonly' value='" + tituloGuion + "' /></td></tr>");
                    sb.Append("<tr><td><label>Descripción:</label></td></tr><tr>");
                    sb.Append("<td><textarea style='width:98%' readonly='readonly' >" + descripcion + "</textarea></td></tr>");
                    sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();
                
                resultado = MailClient().SendMail(destinatarios, asunto, cuerpo);
            }
            catch (Exception)
            {
	            throw;
            }
            return resultado;
        }

        /// <summary>
        /// Enviar mail de Solicitud Autorización de Guión
        /// </summary>
        /// <param name="destinatarios"></param>
        /// <param name="guion"></param>
        /// <param name="tipoAutorizacion"></param>
        /// <param name="usuarioEmisor"></param>
        /// <param name="usuarioNotificado"></param>
        /// <returns></returns>
        public static bool EnviarMailSolicitudAutorizacionGuion(Dictionary<string, string> destinatarios, string guion, string tipoAutorizacion, string usuarioEmisor, string usuarioNotificado)
        {
            var resultado = false;
            try 
	        {	        
                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;' >Solicitud de autorización de Guión</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%' >");
                    sb.Append("<colgroup><col width='100%' /></colgroup>");
                    sb.Append("<tr><td><span>Tipo de autorización:</span>&nbsp;<span><b>" + tipoAutorizacion + "</b></span></td></tr>");
                    sb.Append("<tr><td><span>Notificado por:</span>&nbsp;<span><b>" + usuarioEmisor + "</b></span></td></tr>");
                    sb.Append("<tr><td><span>Guión:</span>&nbsp;<span><b>" + guion + "</b></span></td></tr>");
                    sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

	            var asunto = String.Format("Se ha Notificado al usuario {0} una autorización de {1} para el guión: {2}.", usuarioNotificado, tipoAutorizacion, guion);

                resultado = MailClient().SendMail(destinatarios, asunto, cuerpo);
            }
            catch (Exception)
            {
	            throw;
            }
            return resultado;
        }

        /// <summary>
        /// Enviar mail de reclamo
        /// </summary>
        /// <param name="destinatarios"></param>
        /// <param name="titulo"></param>
        /// <param name="descripcion"></param>
        /// <param name="fecha"></param>
        /// <param name="usuario"></param>
        /// <returns></returns>
        public static bool EnviarMailNotificacionGuionFinalizado(Dictionary<string, string> destinatarios, string asunto, string programa, DateTime fecha, string director)
        {
            var resultado = false;
            try 
	        {	        
                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;' >Terminación de Programa</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%' >");
                    sb.Append("<colgroup><col width='100%' /></colgroup>");
                    sb.Append("<tr><td><label>Fecha:</label></td></tr>");
                    sb.Append("<tr><td><input type='text' style='width:98%' readonly='readonly' value='" + fecha.ToShortDateString() + "' /></td></tr>");
                    sb.Append("<tr><td><label>Asunto:</label></td></tr><tr>");
                    sb.Append("<td><input type='text' style='width:98%' readonly='readonly' value='" + asunto + "' /></td></tr>");
                    sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

                resultado = MailClient().SendMail(destinatarios, asunto, cuerpo);
            }
            catch (Exception)
            {
	            throw;
            }
            return resultado;
        }

        /// <summary>
        /// Envía mail notificando el pago de un Guión
        /// </summary>
        /// <param name="destinatarios"></param>
        /// <param name="asunto"></param>
        /// <param name="programa"></param>
        /// <param name="fechaGuion"></param>
        /// <param name="medioPago"></param>
        /// <param name="fechaPago"></param>
        /// <returns></returns>
        public static bool EnviarMailNotificacionGuionPagado(Dictionary<string, string> destinatarios, string asunto, string programa, DateTime fechaGuion, string medioPago, DateTime fechaPago)
        {
            var resultado = false;
            try 
	        {	        
                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;padding: 5px; margin: 5px;' >Detalle del pago realizado</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%'><colgroup><col width='40%'><col width='10%'><col width='10%'><col width='10%'><col width='10%'><col width='20%'><col width='10%'></colgroup>");
                    sb.Append("<thead>");
	                sb.Append("<tr>");
                    sb.Append("<th>Programa</th>");
                    sb.Append("<th>Fecha</th>");
                    sb.Append("<th>Medio Pago</th>");
                    sb.Append("<th>Fecha Pago</th>");
	                sb.Append("</tr>");
                    sb.Append("</thead>");
	                sb.Append("<tbody>");
                    sb.Append("<tr style='text-align:center'>");
                    sb.Append("<td>" + programa +"</td>");
                    sb.Append("<td>" + fechaGuion.ToShortDateString() + "</td>");
                    sb.Append("<td>" + medioPago + "</td>");
                    sb.Append("<td>" + fechaPago.ToShortDateString() + "</td>");
                    sb.Append("</tr>");
                    sb.Append("</tbody>");
	                sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

	            resultado = MailClient().SendMail(destinatarios, asunto, cuerpo);
	        }
            catch (Exception)
            {
	            throw;
            }
            return resultado;
        }

        /// <summary>
        /// Envía mail notificando el pago de un Guión
        /// </summary>
        /// <param name="pago"></param>
        /// <param name="onEnvioCompletado"></param>
        /// <returns></returns>
        public static bool EnviarMailNotificacionGuionPagado(Pago pago, Action<bool, MailMessage, object, Action<Exception>> onEnvioCompletado, string asunto2 = null)
        {
            var resultado = false;
            try
            {
                var isValidEmailAddress = Email.ValidateEmailAddress( pago.Proveedor.Email );
                if ( !isValidEmailAddress )
                    return true;

                var destinatarios   = MailHelper.CreateRecipientsList( pago.Proveedor.Email, pago.Proveedor.Descriptor );
                var asunto          = "Notificación de pago realizado " + asunto2;
                var programa        = String.Format("Ep. {0} - {1}", pago.Guion.Episodio, pago.Guion.Titulo);
                var fechaGuion      = pago.Guion.FechaCreacion;
                var fechaPago       = DateTime.Now;
                var medioPago       = pago.MedioPago.Nombre;
                var loops           = pago.Loops;
                var importe         = pago.ImporteTotal;

                var sb = new StringBuilder();
                    sb.Append("<div style='width:99%; border:0px solid Transparent; outline:none;' >");
                    sb.Append("<fieldset style='-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -khtml-border-radius: 5px; border: 1px solid #A6C9E2; background: #FCFDFD; color: #222; font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size:12px;' >");
                    sb.Append("<legend style='border:1px solid #686970; background-color: #959AC2; color: white; font-weight: bold;padding: 5px; margin: 5px;' >Detalle de los pagos realizados</legend>");
                    sb.Append("<table border='0' cellpadding='0' cellspacing='0' width='99%'><colgroup><col width='40%'><col width='10%'><col width='10%'><col width='10%'><col width='10%'><col width='20%'><col width='10%'></colgroup>");
                    sb.Append("<thead>");
	                sb.Append("<tr>");
                    sb.Append("<th>Programa</th>");
                    sb.Append("<th>Fecha</th>");
                    sb.Append("<th>Loops</th>");
                    sb.Append("<th>Importe</th>");
                    sb.Append("<th>Medio Pago</th>");
                    sb.Append("<th>Fecha Pago</th>");
	                sb.Append("</tr>");
                    sb.Append("</thead>");
	                sb.Append("<tbody>");
                    sb.Append("<tr style='text-align:center'>");
                    sb.Append("<td>" + programa +"</td>");
                    sb.Append("<td>" + fechaGuion.ToShortDateString() + "</td>");
                    sb.Append("<td>" + loops + "</td>");
                    sb.Append("<td>" + importe + "</td>");
                    sb.Append("<td>" + medioPago + "</td>");
                    sb.Append("<td>" + fechaPago.ToShortDateString() + "</td>");
                    sb.Append("</tr>");
                    sb.Append("</tbody>");
	                sb.Append("</table>");
                    sb.Append("</fieldset>");
                    sb.Append("</div>");
                var cuerpo = sb.ToString();

                var asyncObjectInfo = new Email.AsyncSendMailCompletedObject()
                {     
                    Object = pago,
                    OnCompleted = onEnvioCompletado
                };

	            resultado = MailClient().SendMail(destinatarios, asunto, cuerpo, asyncObjectInfo);
	        }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                BasePage.LogError(ex);
            }
            return resultado;
        }

        public static bool EnviarMailSms(List<string> numerosCelular, string proyecto, string medioPago)
        {
            var resultado = false;
            try
            {
                var parametroInfo = BasePage.Parametros.Obtener();
                if (parametroInfo == null)
                    return false;

                if (numerosCelular == null || !numerosCelular.Any())
                    return false;

                numerosCelular = numerosCelular.Distinct().ToList();
                var destinatarios = numerosCelular.ToDictionary
                    (
                        address     => String.Format(parametroInfo.SMSNumero, address),
                        displayName => String.Empty
                    );
      
                var asyncObjectInfo = new Email.AsyncSendMailCompletedObject()
                {     
                    Object = null,
                    OnCompleted = OnEnvioMailCompletadoEmpty
                };

                var asunto  =   parametroInfo.SMSClave;
                var cuerpo  =   "Recibiste un pago de Caja de Ruidos!" + Environment.NewLine + Environment.NewLine +
                                String.Format("El proyecto '{0}' fue pagado en {1}. ", proyecto != null ? proyecto.ToUpper() : "<PROYECTO>", medioPago != null ? medioPago.ToUpper() : "<MEDIO_DE_PAGO>" ) +
                                "El detalle se encuentra disponible en tu correo." + Environment.NewLine +
                                "Saludos!";

	            resultado = MailClient().SendMail(destinatarios, asunto, cuerpo, asyncObjectInfo);
	        }
            catch (Exception ex)
            {
	            //throw; <== trap exception to avoid code flow interruption
                BasePage.LogError( ex );
            }
            return resultado;
        }

        /// <summary>
        /// Callback function raised when an async mail sending is completed
        /// </summary>
        /// <param name="resultado"></param>
        /// <param name="mailMessage"></param>
        /// <param name="obj"></param>
        /// <param name="logErrorFunction"></param>
        public static void OnEnvioMailCompletado(bool resultado, MailMessage mailMessage, object obj, Action<Exception> logErrorFunction = null)
        {
            try
            {
                var mail = new Mail()
                {
                    Fecha = DateTime.Now,
                    Asunto = mailMessage.Subject,
                    Cuerpo = mailMessage.Body,
                    Destinatarios = mailMessage.GetRecipients(),
                    Resultado = resultado
                };
                var saveOk = new ControladorBase<Mail>().GuardarEntidad(mail);
                if (saveOk)
                {
                    var controladorPago = new ControladorBase<Pago>();
                    var pago = controladorPago.ObtenerEntidad(((Pago) obj).Id);
                    if (pago.IsNotNull())
                    {
                        pago.Mail = mail;
                        pago.UsuarioUltimaModificacion = new ControladorBase<Usuario>().ObtenerEntidad( Helpers.SessionHelper.GetCurrentUser().Id );
                        pago.FechaUltimaModificacion = DateTime.Now;
                        controladorPago.GuardarEntidad(pago);
                    }

                }
            }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                if ( logErrorFunction != null )
                    logErrorFunction(ex);
            }
            finally
            {
                mailMessage.Dispose();
                ((IDisposable)obj).Dispose();
            }
        }

        private static void OnEnvioMailCompletadoEmpty(bool resultado, MailMessage mailMessage, object obj, Action<Exception> logErrorFunction = null)
        {
            try
            {
            }
            catch (Exception ex)
            {
                //throw; <== trap exception to avoid code flow interruption
                if ( logErrorFunction != null )
                    logErrorFunction(ex);
            }
        }

        #endregion

        #region Private Methods
        private static Email MailClient()
        {
            Email email = null;
            try
            {
                var parametro = BasePage.Parametros.Obtener();
                if (parametro.IsNotNull())
                {
                    //var config = new ControladorBase<Parametro>().ObtenerEntidad();
                    email = new Email
                            (
                                parametro.EmailNombre,
                                parametro.EmailNombreUsuario,
                                parametro.EmailPassword,
                                parametro.EmailSMTP,
                                parametro.EmailPuerto,
                                parametro.EmailHabilitarSSL
                            );
                }
            }
            catch (Exception ex)
            {
                // throw ex;
                BasePage.LogError( ex );
            }
            return email;
        }
        #endregion
    }
}